import { useCallback, useState, useRef, useMemo, } from 'react';
import { Button, Modal, message, Tabs } from 'antd';
import { getMessage, TextWidget } from '@inbiz/react';
import { useForm } from '@formily/react';
import type { IModelApi } from './ModelApi';
import type { ICustomApi, ICustomApiValue } from './CustomApi/index';
import Content from './Content';
import { saveApiData } from './utils';
import './index.less';
export { default as ServerModal} from './ServerModal'
export { default as CustomApi} from './CustomApi'
export type {ICustomApiValue}
export {default as QueryContent} from './QueryContent'
type IProps = {
  value:
  | string
  | { modelKey: string; primaryKey?: string; queryField?: [] }
  | ICustomApiValue
  | {
    searchData: string | ICustomApiValue | undefined;
    editData: string | ICustomApiValue | undefined;
  };
  onChange: (data: IProps['value']) => void;
  onBlur?: () => void;
  resultKeys?: string[]; // 自定义接口出参字段
  isPrimaryKey?: boolean; // 自定义接口唯一标识
  isEdit?: boolean; // 是否启动编辑配置
  isDatasource?: boolean; // 是不是用于数据源
  open?: boolean; // 在可编辑表格里面使用
  variableOptions?: string[] | { label: string; value: string }[]; // 接口工厂- 控件变量下拉提示
};
const DataQuery = ({
  value,
  onChange,
  resultKeys,
  isPrimaryKey,
  isDatasource = true,
  isEdit = false,
  variableOptions,
  onBlur,
  open,
}: IProps) => {
  const form = useForm();
  const [apiType, $apiType] = useState(() => {
    if (!value || typeof value === 'string' || 'modelKey' in value) {
      return 1;
    }
    // 兼容动态列表老版数据
    if (value?.searchData) {
      if (typeof value.searchData === 'string') {
        return 1;
      }
      return 2;
    }
    return 2;
  });
  const [editApiType, $editApiType] = useState(() => {
    if (!value || typeof value === 'string') {
      return 1;
    }
    // 兼容动态列表老版数据
    if (value?.editData) {
      if (typeof value.editData === 'string') {
        return 1;
      }
      return 2;
    }
    return 2;
  });

  const [visible, $visible] = useState<boolean>(open ?? false);
  const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
  const [activeKey, setActiveKey] = useState('search')

  const modelApiRef = useRef<IModelApi>(null);
  const customApiRef = useRef<ICustomApi>(null);
  const editModelApiRef = useRef<IModelApi>(null);
  const editCustomApiRef = useRef<ICustomApi>(null);

  const handleOk = useCallback(async () => {
    const sourceModelUpdate = isDatasource
      ? form?.query(/sourceModelUpdate$/)?.take()
      : undefined;
    const oldValue = JSON.parse(sourceModelUpdate?.['value'] || '{}');
    delete oldValue.oldValue;
    // 兼容动态列表老版数据源
    if (isEdit) {
      try {
        setConfirmLoading(true);
        let searchValue = {};
        let editValue = {};
        let searchCustomApi: ICustomApiValue | undefined = undefined;
        let editCustomApi: ICustomApiValue | undefined = undefined;
        // 获取查询tab的接口工厂或自定义api的配置进行保存
        if (apiType == 1) {
          const queryData = modelApiRef.current?.getData();
          searchValue = await saveApiData({
            queryData,
            value: value?.searchData,
            interfaceType: 1,
            isPrimaryKey,
            form
          })
        } else {
          searchCustomApi = await customApiRef.current?.getValue();
        }
        // 获取编辑tab的接口工厂或自定义api的配置进行保存
        if (editApiType == 1) {
          const queryData = editModelApiRef.current?.getData();
          editValue = await saveApiData({
            queryData,
            value: value?.editData,
            interfaceType: 2,
            isPrimaryKey,
            form
          })
        } else {
          editCustomApi = await editCustomApiRef.current?.getValue();
        }
        //数据时 只能是一个字符串, 相信信息保存到sourceModelUpdate中a
        onChange(
          {
            searchData: apiType == 1 ? searchValue.value : searchCustomApi,
            editData: editApiType == 1 ? editValue.value : editCustomApi
          }
        );
        if (sourceModelUpdate && 'value' in sourceModelUpdate) {
          const _value = {
            searchData: apiType == 1 ? { ...searchValue, oldValue } : {
              date: Date.now(),
              sourcetype: 'custom',
              primaryKey: searchCustomApi?.result?.primaryKey ?? '',
              ...searchCustomApi,
              oldValue,
            },
            editData: editApiType == 1 ? { ...editValue, oldValue } : {
              date: Date.now(),
              sourcetype: 'custom',
              primaryKey: editCustomApi?.result?.primaryKey ?? '',
              ...editCustomApi,
              oldValue,
            }
          }
          sourceModelUpdate.value = JSON.stringify(_value);
        }
      } catch (e) {
        setConfirmLoading(false);
        if (apiType == 1 || editApiType == 1) {
          message.error('数据源需配置完整的查询和编辑参数，请检查查询或编辑配置项完整度');
        }
        return;
      }
      $visible(false);
      setConfirmLoading(false);
      // 延迟动画执行时间
      setTimeout(() => {
        onBlur?.();
      }, 300);
    } else {
      // 新版数据源
      try {
        if (apiType == 1) {
          setConfirmLoading(true);
          const value = await modelApiRef.current?.getValue();
          //数据时 只能是一个字符串, 相信信息保存到sourceModelUpdate中
          onChange(
            isDatasource
              ? value!.value
              : {
                modelKey: value!.value,
                primaryKey: value?.primaryKey ?? '',
              },
          );
          if (sourceModelUpdate && 'value' in sourceModelUpdate) {
            sourceModelUpdate.value = JSON.stringify({
              ...value,
              oldValue,
            });
          }
        } else {
          const value = await customApiRef.current?.getValue();
          onChange(value!);
          if (sourceModelUpdate && 'value' in sourceModelUpdate) {
            sourceModelUpdate.value = JSON.stringify({
              date: Date.now(),
              sourcetype: 'custom',
              primaryKey: value?.result?.primaryKey ?? '',
              ...value,
              oldValue,
            });
          }
        }
        $visible(false);
        setConfirmLoading(false);
        // 延迟动画执行时间
        setTimeout(() => {
          onBlur?.();
        }, 300);
      } catch (e) {
        setConfirmLoading(false);
        if (apiType == 1) {
          message.error(getMessage(e as string));
        }
      }
    }
  }, [apiType, editApiType, value, onChange, isDatasource, onBlur]);
  const handleCancel = useCallback(() => {
    $visible(false);
    // 延迟动画执行时间
    setTimeout(() => {
      onBlur?.();
    }, 300);
  }, [onBlur]);
  const [modelValue, customApiValue, editModelValue, editCustomApiValue] = useMemo(() => {
    const values: [string | undefined, object | undefined, string | undefined, object | undefined] = [
      undefined,
      undefined,
      undefined,
      undefined,
    ];
    if (value) {
      if (typeof value === 'string') {
        values[0] = value;
        values[2] = value;
      } else {
        // 动态列表老版数据兼容处理
        if ('searchData' in value && 'editData' in value) {
          if ('searchData' in value) {
            if (typeof value.searchData === 'string') {
              values[0] = value.searchData;
            } else {
              values[1] = value.searchData;
            }
          }
          if ('editData' in value) {
            if (typeof value.editData === 'string') {
              values[2] = value.editData;
            } else {
              values[3] = value.editData;
            }
          }
        } else {
          // 新版数据处理
          if ('modelKey' in value) {
            values[0] = value.modelKey;
          } else {
            values[1] = value;
          }
        }
      }
    }
    return values;
  }, [value]);

  const onTabClick = useCallback((key: string) => {
    setActiveKey(key)
  }, []);

  return (
    <>
      {!open && (
        <Button type="primary" onClick={() => $visible(true)}>
          <TextWidget>ApiQuery.configButton</TextWidget>
        </Button>
      )}
      <Modal
        title="数据源配置"
        visible={visible}
        okText={getMessage('ApiQuery.ok')}
        cancelText={getMessage('ApiQuery.cancel')}
        destroyOnClose
        onOk={handleOk}
        onCancel={handleCancel}
        width={1000}
        className="ApiQueryModal"
        keyboard={false}
        maskClosable={false}
        confirmLoading={confirmLoading}
      >
        {
          isEdit ? (
            <Tabs activeKey={activeKey} onTabClick={onTabClick}>
              <Tabs.TabPane
                key="search"
                tab={<TextWidget>ApiQuery.query</TextWidget>}
                forceRender
              >
                <Content
                  type='search'
                  apiType={apiType}
                  modelValue={modelValue}
                  customApiValue={customApiValue}
                  resultKeys={resultKeys}
                  isPrimaryKey={isPrimaryKey}
                  variableOptions={variableOptions}
                  modelApiRef={modelApiRef}
                  customApiRef={customApiRef}
                  $apiType={$apiType}
                />
              </Tabs.TabPane>
              <Tabs.TabPane
                key="edit"
                tab={<TextWidget>ApiQuery.edit</TextWidget>}
                forceRender
              >
                <Content
                  type='edit'
                  apiType={editApiType}
                  modelValue={editModelValue}
                  customApiValue={editCustomApiValue}
                  resultKeys={resultKeys}
                  isPrimaryKey={isPrimaryKey}
                  variableOptions={variableOptions}
                  modelApiRef={editModelApiRef}
                  customApiRef={editCustomApiRef}
                  $apiType={$editApiType}
                />
              </Tabs.TabPane>
            </Tabs>
          ) :
            <Content
              apiType={apiType}
              modelValue={modelValue}
              customApiValue={customApiValue}
              resultKeys={resultKeys}
              isPrimaryKey={isPrimaryKey}
              variableOptions={variableOptions}
              modelApiRef={modelApiRef}
              customApiRef={customApiRef}
              $apiType={$apiType}
            />
        }
      </Modal>
    </>
  );
};

export default DataQuery;
